package site.timers.game;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapRenderer;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.Input;
import java.util.ArrayList;
import java.util.List;

public class Main extends ApplicationAdapter {
    private enum GameState {
        MENU, PLAYING
    }

    private GameState gameState = GameState.MENU;
    private OrthographicCamera camera;
    private SpriteBatch batch;
    private Texture menuBackground;
    private BitmapFont font;
    private TiledMap map;
    private TiledMapRenderer renderer;
    private List<Character> characters;
    private boolean playerTurn;
    private List<String> battleLog = new ArrayList<>();
    private boolean showInventory;
    private Inventory playerInventory;

    @Override
    public void create() {
        if (gameState == GameState.MENU) {
            batch = new SpriteBatch();
            try {
                menuBackground = new Texture("images/menu_bg.jpg");
            } catch (Exception e) {
                System.out.println("loading menu background failed: " + e.getMessage());
                // 创建一个1x1的纯色纹理作为备用
                Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGB888);
                pixmap.setColor(0, 0, 0, 1);
                pixmap.fill();
                menuBackground = new Texture(pixmap);
                pixmap.dispose();
            }

            // 使用中文字体
            try {
                FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/simhei.ttf"));
                FreeTypeFontParameter parameter = new FreeTypeFontParameter();
                // 字体大小
                parameter.size = 24;
                parameter.characters = FreeTypeFontGenerator.DEFAULT_CHARS + "开始游戏退出物品栏铁剑皮甲魔法戒指基础武器护甲增加魔抗玩家敌人级经验值获得升级当前等级攻击被闪避暴击造成伤害目标被击败";
                font = generator.generateFont(parameter);
                generator.dispose();
                font.getData().setScale(1.5f);
            } catch (Exception e) {
                // 如果加载失败，使用默认字体
                System.out.println("loading fonts failed: " + e.getMessage());
                font = new BitmapFont();
                font.getData().setScale(1.5f);
            }
            return;
        }

        System.out.println("game started");
    }

    @Override
    public void render() {
        if (gameState == GameState.MENU) {
            renderMenu();
        } else if (gameState == GameState.PLAYING) {
            renderGame();
        }
    }

    private void renderMenu() {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        // 确保batch和font已初始化
        if (batch == null) {
            batch = new SpriteBatch();
        }

        if (font == null) {
            font = new BitmapFont();
            font.getData().setScale(1.5f);
        }

        try {
            batch.begin();
            // 绘制菜单背景
            if (menuBackground != null) {
                batch.draw(menuBackground, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
            }

            // 绘制开始按钮文本
            font.draw(batch, "开始游戏",
                (float) Gdx.graphics.getWidth() / 2 - 50,
                (float) Gdx.graphics.getHeight() / 2 + 10);

            // 绘制退出按钮文本
            font.draw(batch, "退出游戏",
                (float) Gdx.graphics.getWidth() / 2 - 50,
                (float) Gdx.graphics.getHeight() / 2 - 60);

            // 处理菜单点击
            if (Gdx.input.justTouched()) {
                float touchY = Gdx.graphics.getHeight() - Gdx.input.getY();

                if (Gdx.input.getX() >= Gdx.graphics.getWidth() / 2 - 100 &&
                    Gdx.input.getX() <= Gdx.graphics.getWidth() / 2 + 100 &&
                    touchY >= (float) Gdx.graphics.getHeight() / 2 - 20 &&
                    touchY <= (float) Gdx.graphics.getHeight() / 2 + 20) {
                    gameState = GameState.PLAYING;
                    initGame();
                }

                if (Gdx.input.getX() >= Gdx.graphics.getWidth() / 2 - 100 &&
                    Gdx.input.getX() <= Gdx.graphics.getWidth() / 2 + 100 &&
                    touchY >= (float) Gdx.graphics.getHeight() / 2 - 80 &&
                    touchY <= (float) Gdx.graphics.getHeight() / 2 - 40) {
                    Gdx.app.exit();
                }
            }
        } catch (Exception e) {
            System.out.println("rendering menu failed: " + e.getMessage());
        } finally {
            // 确保batch.end()在任何情况下都被调用
            if (batch != null && batch.isDrawing()) {
                batch.end();
            }
        }
    }

    private void initGame() {
        float w = Gdx.graphics.getWidth();
        float h = Gdx.graphics.getHeight();

        camera = new OrthographicCamera();
        camera.setToOrtho(false, w, h);
        camera.update();

        batch = new SpriteBatch();
        // 使用中文字体
        try {
            FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/simhei.ttf"));
            FreeTypeFontParameter parameter = new FreeTypeFontParameter();
            // 游戏中使用较小的字体
            parameter.size = 16;
            parameter.characters = FreeTypeFontGenerator.DEFAULT_CHARS + "开始游戏退出物品栏铁剑皮甲魔法戒指基础武器护甲增加魔抗玩家敌人级经验值获得升级当前等级攻击被闪避暴击造成伤害目标被击败";
            font = generator.generateFont(parameter);
            generator.dispose();
            font.getData().setScale(0.5f);
        } catch (Exception e) {
            // 如果加载失败，使用默认字体
            System.out.println("loading fonts failed: " + e.getMessage());
            font = new BitmapFont();
        }
        map = new TmxMapLoader().load("maps/map.tmx");
        renderer = new OrthogonalTiledMapRenderer(map);

        characters = new ArrayList<>();
        Texture zichuanxiuTexture = new Texture("images/zichuanxiu.png");
        Texture sitelinTexture = new Texture("images/sitelin.png");
        Texture dilinTexture = new Texture("images/dilin.png");

        // 添加玩家角色和敌人
        characters.add(new Character(zichuanxiuTexture, 2, 2, true));
        characters.add(new Character(sitelinTexture, 5, 5, false));
        characters.add(new Character(dilinTexture, 3, 3, true));

        playerTurn = true;

        // 初始化玩家物品栏
        playerInventory = new Inventory(10);
        playerInventory.addItem(new Equipment("铁剑", "基础武器", 5, 0, 0));
        playerInventory.addItem(new Equipment("皮甲", "基础护甲", 0, 3, 1));
        playerInventory.addItem(new Equipment("魔法戒指", "增加魔抗", 0, 0, 3));
    }



    private void renderGame() {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        camera.update();
        renderer.setView(camera);
        renderer.render();

        batch.begin();

        Texture libgdxTexture = new Texture("libgdx.png");
        // 绘制角色和血条
        for (Character character : characters) {
            character.render(batch);

            // 绘制血条背景
            batch.setColor(1, 0, 0, 0.5f);
            batch.draw(new TextureRegion(libgdxTexture),
                     character.getX() * 32, character.getY() * 32 + 30, 32, 5);

            // 绘制当前血量
            batch.setColor(0, 1, 0, 0.8f);
            float healthPercent = (float)character.getHealth() / character.getMaxHealth();
            batch.draw(new TextureRegion(libgdxTexture),
                     character.getX() * 32, character.getY() * 32 + 30, 32 * healthPercent, 5);

            // 绘制等级
            font.draw(batch, "Lv." + character.getLevel(),
                    character.getX() * 32 + 2, character.getY() * 32 + 28);

            // 绘制经验条(仅对玩家角色)
            if (character.isPlayer()) {
                batch.setColor(0, 0.5f, 1, 0.5f);
                float expPercent = (float)character.getExp() / (character.getLevel() * 100);
                batch.draw(new TextureRegion(libgdxTexture),
                         character.getX() * 32, character.getY() * 32 + 25, 32 * expPercent, 3);
            }

            // 重置颜色
            batch.setColor(1, 1, 1, 1);
        }

        // 绘制可移动区域
        if (selectedCharacter != null) {
            for (int[] tile : moveableTiles) {
                batch.setColor(0, 1, 0, 0.3f);
                batch.draw(new TextureRegion(libgdxTexture),
                          tile[0] * 32, tile[1] * 32, 32, 32);
            }
        }

        // 重置颜色
        batch.setColor(1, 1, 1, 1);
        batch.end();

        // 绘制战斗日志
        if (!battleLog.isEmpty()) {
            batch.begin();
            for (int i = 0; i < Math.min(3, battleLog.size()); i++) {
                String log = battleLog.get(battleLog.size() - 1 - i);
                font.draw(batch, log, 10, Gdx.graphics.getHeight() - 20 - i * 20);
            }
            batch.end();
        }

        // 绘制物品栏界面
        if (showInventory) {
            batch.begin();
            batch.setColor(0, 0, 0, 0.8f);
            batch.draw(new TextureRegion(libgdxTexture),
                     100, 100, Gdx.graphics.getWidth() - 200, Gdx.graphics.getHeight() - 200);
            batch.setColor(1, 1, 1, 1);

            font.draw(batch, "物品栏 (I键关闭)", 120, Gdx.graphics.getHeight() - 120);

            int yPos = Gdx.graphics.getHeight() - 150;
            int selectedIndex = 0;
            for (int i = 0; i < playerInventory.getItems().size(); i++) {
                Item item = playerInventory.getItems().get(i);
                if (i == selectedIndex) {
                    batch.setColor(1, 1, 0, 1);
                }
                font.draw(batch, (i+1) + ". " + item.getName() + " - " + item.getDescription(), 120, yPos);
                batch.setColor(1, 1, 1, 1);
                yPos -= 30;

                // 处理物品选择
                if (Gdx.input.isKeyJustPressed(Input.Keys.NUM_1 + i) && selectedCharacter != null) {
                    item.use(selectedCharacter);
                    showInventory = false;
                }
            }

            batch.end();

            // 处理物品选择
            if (Gdx.input.isKeyJustPressed(Input.Keys.ESCAPE)) {
                showInventory = false;
            }
            return;
        }

        // 绘制选中角色信息和技能界面
        if (selectedCharacter != null) {
            batch.begin();
            // 角色基本信息
            font.draw(batch, "Lv." + selectedCharacter.getLevel() + " " +
                     (selectedCharacter.isPlayer() ? "玩家" : "敌人"),
                     Gdx.graphics.getWidth() - 100, 50);
            font.draw(batch, "HP: " + selectedCharacter.getHealth() + "/" + selectedCharacter.getMaxHealth(),
                     Gdx.graphics.getWidth() - 100, 30);
            font.draw(batch, "MP: " + selectedCharacter.getMana() + "/" + selectedCharacter.getMaxMana(),
                     Gdx.graphics.getWidth() - 100, 10);
            font.draw(batch, "魔抗: " + selectedCharacter.getMagicResist(),
                     Gdx.graphics.getWidth() - 100, -10);

            // 显示装备信息
            font.draw(batch, "武器: " + (selectedCharacter.getWeapon() != null ?
                     selectedCharacter.getWeapon().getName() : "无"),
                     Gdx.graphics.getWidth() - 100, -30);
            font.draw(batch, "护甲: " + (selectedCharacter.getArmor() != null ?
                     selectedCharacter.getArmor().getName() : "无"),
                     Gdx.graphics.getWidth() - 100, -50);
            font.draw(batch, "饰品: " + (selectedCharacter.getAccessory() != null ?
                     selectedCharacter.getAccessory().getName() : "无"),
                     Gdx.graphics.getWidth() - 100, -70);

            // 技能选择界面
            if (selectedCharacter.isPlayer()) {
                int yPos = 100;
                for (int i = 0; i < selectedCharacter.getSkills().size(); i++) {
                    Skill skill = selectedCharacter.getSkills().get(i);
                    String skillText = (i+1) + ". " + skill.getName() +
                                     " (MP:" + skill.getCost() + ")";
                    if (skill.getCurrentCooldown() > 0) {
                        skillText += " CD:" + skill.getCurrentCooldown();
                        batch.setColor(0.7f, 0.7f, 0.7f, 1);
                    } else if (selectedCharacter.getMana() < skill.getCost()) {
                        batch.setColor(1, 0.5f, 0.5f, 1);
                    }
                    font.draw(batch, skillText, Gdx.graphics.getWidth() - 100, yPos);
                    batch.setColor(1, 1, 1, 1);
                    yPos += 20;
                }
            }
            batch.end();
        }

        // 物品使用快捷键 (I键打开物品栏)
        if (Gdx.input.isKeyJustPressed(Input.Keys.I) && selectedCharacter != null) {
            showInventory = true;
        }

        // 处理回合逻辑和技能快捷键
        if (playerTurn) {
            // 技能快捷键 (1-3)
            for (int i = 0; i < 3; i++) {
                if (Gdx.input.isKeyJustPressed(Input.Keys.NUM_1 + i) &&
                    selectedCharacter != null &&
                    selectedCharacter.getSkills().size() > i) {
                    Skill skill = selectedCharacter.getSkills().get(i);
                    if (selectedCharacter.getMana() >= skill.getCost() && skill.isReady()) {
                        // 使用技能
                        selectedCharacter.useSkill(skill, findTargetForSkill(selectedCharacter, skill));
                        playerTurn = false;
                    }
                }
            }

            // 鼠标点击移动
            if (Gdx.input.justTouched()) {
                handlePlayerInput();
                playerTurn = false;
            }
        } else {
            // AI回合
            handleAI();
            playerTurn = true;
        }

        // 更新所有角色技能冷却
        for (Character character : characters) {
            character.updateSkills();
        }
    }

    private Character selectedCharacter;
    private List<int[]> moveableTiles = new ArrayList<>();

    private void handlePlayerInput() {
        if (Gdx.input.justTouched()) {
            int x = (int)(Gdx.input.getX() / 32);
            int y = (int)((Gdx.graphics.getHeight() - Gdx.input.getY()) / 32);

            if (selectedCharacter == null) {
                // 选择角色
                for (Character character : characters) {
                    if (character.isPlayer() && character.getX() == x && character.getY() == y) {
                        selectedCharacter = character;
                        calculateMoveRange(selectedCharacter);
                        break;
                    }
                }
            } else {
                // 检查是否点击可移动区域
                for (int[] tile : moveableTiles) {
                    if (tile[0] == x && tile[1] == y) {
                        selectedCharacter.moveTo(x, y);
                        selectedCharacter = null;
                        moveableTiles.clear();
                        break;
                    }
                }

                // 取消选择
                if (selectedCharacter != null && selectedCharacter.getX() == x && selectedCharacter.getY() == y) {
                    selectedCharacter = null;
                    moveableTiles.clear();
                }
            }
        }
    }

    private void calculateMoveRange(Character character) {
        int startX = character.getX();
        int startY = character.getY();
        int range = character.getMoveRange();

        for (int dx = -range; dx <= range; dx++) {
            for (int dy = -range; dy <= range; dy++) {
                if (Math.abs(dx) + Math.abs(dy) <= range) {
                    int newX = startX + dx;
                    int newY = startY + dy;
                    if (newX >= 0 && newX < 10 && newY >= 0 && newY < 10) {
                        moveableTiles.add(new int[]{newX, newY});
                    }
                }
            }
        }
    }

    private Character findTargetForSkill(Character caster, Skill skill) {
        // 简单目标选择逻辑：最近的敌人
        Character target = null;
        int minDistance = Integer.MAX_VALUE;

        for (Character character : characters) {
            if (character.isPlayer() != caster.isPlayer()) {
                int distance = Math.abs(character.getX() - caster.getX()) +
                             Math.abs(character.getY() - caster.getY());
                if (distance <= skill.getRange() && distance < minDistance) {
                    minDistance = distance;
                    target = character;
                }
            }
        }
        return target;
    }

    private void handleAI() {
        for (Character enemy : characters) {
            if (!enemy.isPlayer()) {
                // 寻找最近的玩家角色
                Character target = findNearestPlayer(enemy);
                if (target != null) {
                    // 移动到可攻击范围
                    moveTowardsTarget(enemy, target);

                    // 检查是否在攻击范围内
                    if (Math.abs(enemy.getX() - target.getX()) +
                        Math.abs(enemy.getY() - target.getY()) == 1) {
                        int attackResult = enemy.attack(target);
                        if (attackResult == -1) {
                            battleLog.add("攻击被闪避!");
                        } else if (attackResult == 1) {
                            battleLog.add("暴击! 造成 " + (enemy.getAttack() * 2 - target.getDefense()) + " 伤害");
                        } else {
                            battleLog.add("造成 " + (enemy.getAttack() - target.getDefense()) + " 伤害");
                        }

                        if (target.getHealth() <= 0) {
                            // 击败敌人获得经验值
                            if (enemy.isPlayer()) {
                                target.gainExp(50);
                                battleLog.add("获得50经验值!");
                            }

                            characters.remove(target);
                            battleLog.add("目标被击败!");

                            // 显示升级信息
                            if (enemy.isPlayer() && target.getExp() == 0) {
                                battleLog.add("升级! 当前等级: " + target.getLevel());
                            }
                        }
                    }
                }
            }
        }
    }

    private Character findNearestPlayer(Character enemy) {
        Character nearest = null;
        int minDistance = Integer.MAX_VALUE;

        for (Character character : characters) {
            if (character.isPlayer()) {
                int distance = Math.abs(enemy.getX() - character.getX()) +
                             Math.abs(enemy.getY() - character.getY());
                if (distance < minDistance) {
                    minDistance = distance;
                    nearest = character;
                }
            }
        }
        return nearest;
    }

    private void moveTowardsTarget(Character enemy, Character target) {
        int dx = target.getX() - enemy.getX();
        int dy = target.getY() - enemy.getY();

        // 简单移动逻辑：优先减少x或y差距
        if (Math.abs(dx) > Math.abs(dy)) {
            enemy.moveTo(enemy.getX() + (dx > 0 ? 1 : -1), enemy.getY());
        } else {
            enemy.moveTo(enemy.getX(), enemy.getY() + (dy > 0 ? 1 : -1));
        }
    }

    @Override
    public void dispose() {
        if (menuBackground != null) menuBackground.dispose();
        if (batch != null) batch.dispose();
        if (map != null) map.dispose();
    }
}
